﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jzy.Model;

using Jzy.DAL.Mail;
using System.Data;
using Jzy.Model.Mail;
using System.Transactions;

using LumiSoft.Net.POP3.Client;
using LumiSoft.Net.Mime;
using System.Threading;

using Frame.Lib.Core.Base;
using Frame.Lib.Core.Attach;
using Frame.Lib.Enums;
using Frame.Lib.Core.Log;
using Jzy.DAL;

namespace Jzy.BLL.Mail
{
    public class WebMailBO:CommonOperate<WebMailInfo>
    {
        private WebMailDAL _mail;
        protected override BaseDAL DAL
        {
            get
            {
                return _mail;
            }
        }
        private int _userID;
        private POP3Client pop;
        private SMTPClient smtp;

        public WebMailBO(int userID):base("WebMail")
        {
            _userID = userID;
            _mail = new WebMailDAL(userID);
            pop = new POP3Client(_userID);
            smtp = new SMTPClient(_userID);
        }
               

        internal void Clear(object folderID)
        {
            _mail.Clear(folderID);
        }
        public override void Delete(IEnumerable<int> ids)
        {
            foreach (int id in ids)
            {
                this.Delete(id);
            }
        }

        public override void Delete(IEnumerable<string> ids)
        {
            foreach (string id in ids)
            {
                this.Delete(id);
            }
        }

        public override void Delete(int id)
        {
            AttachBO attach = new AttachBO("WebMail");           

            attach.DeleteByBindID(id);

            base.Delete(id);
        }       

        public bool Send(WebMailAccountInfo accountInfo, WebMailInfo info, System.Web.HttpFileCollection files,List<int> lstForwordAttachIDs, Jzy.Model.Mail.WriteMailMode mode)
        {
            info.FromName = accountInfo.DispName;
            info.FromAddr = accountInfo.MailAddr;
            info.AccountAddr = accountInfo.MailAddr;
            info.FolderID = (int)MailSysFolder.已发送;
            info.Status = (int)MailStatus.HaveRead;

            int mailID = 0;//先取回原来邮件的ＩＤ，然后再清空便于插入新记录
            if (mode == WriteMailMode.Reply || mode == WriteMailMode.Forword)
            {
                mailID = info.ID;
                info.ID = 0;
            }

            bool flag = false;
            
            //using (TransactionScope scope = new TransactionScope())
            //{
                try
                {
                    _mail.dbOper.BeginTrans();
                    this.Save(info);

                    //保存附件
                    AttachBO attach = new AttachBO("WebMailAttach");
                    attach.Save(files, info.ID);

                    //复制转发附件,从草稿箱来的附件就不要复制了
                    if (mode == WriteMailMode.Forword)
                    {
                        attach.CopyAttach(lstForwordAttachIDs, info.ID);
                    }

                    IEnumerable<AttachInfo> forwordAttachs = attach.GetList(lstForwordAttachIDs as IEnumerable<int>);

                    smtp.Send(accountInfo, info, files, forwordAttachs);



                    switch (mode)
                    {
                        case WriteMailMode.Draft: //如果来源于草稿箱，则更新，其余为增加
                            info.FolderID = (int)MailSysFolder.已发送;
                            this.Save(info);
                            break;
                        case WriteMailMode.Forword:
                            {
                                //byte status = mail.GetStatus(BoxType.Recieve, mailID);
                                //status =(byte)(status | (int)MailStatus.Forword);
                                _mail.SetStatus(mailID, MailStatus.Forword);//保存修改后的状态
                            }
                            break;
                        case WriteMailMode.Reply:
                            {
                                //byte status = mail.GetStatus(BoxType.Recieve, mailID);
                                //status =(byte)(status | (byte)MailStatus.Reply);
                                _mail.SetStatus(mailID, MailStatus.Reply);//保存修改后的状态
                            }
                            break;
                    }
                   // scope.Complete();
                    _mail.dbOper.CommitTrans();
                    flag = true;
                }
                catch
                {
                    //scope.Dispose();
                    _mail.dbOper.RollbackTrans();
                }
            //}
            return flag;
        }

        public bool SaveToDraft(WebMailInfo info, System.Web.HttpFileCollection files)
        {
            bool flag = true;
          
            try
            {
                info.FolderID = (int)MailSysFolder.草稿箱;
                Save(info);

                //保存附件
                AttachBO attach = new AttachBO(OTableName.WebMailAttach);
                attach.Save(files, info.ID);                   
            }
            catch(Exception ex)
            {
                Logger.Exception(ex);
                flag = false;                    
            }
          
            return flag;
        }


        public List<AttachInfo> DownMail(WebMailAccountInfo accountInfo,string mailGuid,out string body)
        {
            List<AttachInfo> attachs = pop.DownMail(accountInfo, mailGuid,out body);
            return attachs;
        }

        public System.Data.DataTable GetList(int folderID, Jzy.Model.Mail.MailStatus status, WebMailAccountInfo info)
        {
            DataTable dt = _mail.GetList(folderID, status, info.MailAddr);
            dt.Columns.Add("MailFlag");
            foreach (DataRow dr in dt.Rows)
            {
                int bytStatus = (int)dr["Status"];
                switch (bytStatus)
                {
                    case 0:
                        dr["MailFlag"] = "~/common/images/Mail/UnRead.gif";
                        break;
                    case 1:
                        dr["MailFlag"] = "~/common/images/Mail/Read.gif";
                        break;
                    case 3:
                        dr["MailFlag"] = "~/common/images/Mail/Re.gif";
                        break;
                    case 5:
                        dr["MailFlag"] = "~/common/images/Mail/Fw.gif";
                        break;
                    case 7:
                        dr["MailFlag"] = "~/common/images/Mail/ReFw.gif";
                        break;
                }
            }
            return dt;
        }

        public void Move(List<int> lstSelectIDs, object destFolder)
        {
            _mail.Move(lstSelectIDs, destFolder);
        }

        public void Move(int MailID, object destFolder)
        {
            List<int> tmp = new List<int>();
            tmp.Add(MailID);
            _mail.Move(tmp, destFolder);
        }

        public List<string> GetMailGuid()
        {
            return _mail.GetMailGuid();
        }

        public int GetUnreadMailCount()
        {
            int mailCount = _mail.GetUnreadMailCount();
            return mailCount;
        }

        public void SetRead(int MailID)
        {
            _mail.SetStatus(MailID, Jzy.Model.Mail.MailStatus.HaveRead);
        }
        
        public static void Receive(WebMailAccountInfo account)
        {            
            POP3_Client pop3 = new POP3_Client();
            WebMailBO mail = new WebMailBO(account.UserID);
            List<string> mailGuid = mail.GetMailGuid();

            pop3.Connect(account.Pop3Server, account.Pop3Port);
            pop3.Authenticate(account.Pop3User, account.Pop3Pwd, false);

            string strTemp = DateTime.Now.ToString();
            //获取邮件信息列表
            POP3_ClientMessageCollection messages = pop3.Messages;
            foreach (POP3_ClientMessage msg in messages)
            {
                if (mailGuid.Contains(msg.UID))
                {
                    continue;
                }

                //获取这封邮件的内容 

                try
                {

                    //解析从Pop3服务器发送过来的邮件信息
                    Mime header = Mime.Parse(msg.HeaderToByte());
                    Mime message = Mime.Parse(msg.MessageToByte());

                    WebMailInfo mailInfo = new WebMailInfo();
                    mailInfo.AccountAddr = account.MailAddr;


                    mailInfo.Name = string.IsNullOrEmpty(header.MainEntity.Subject) ? "无标题" : header.MainEntity.Subject;

                    if (message != null)
                    {
                        if (message.BodyHtml != null)
                        {
                            mailInfo.Body = message.BodyHtml;
                        }
                        else if (message.BodyText != null)
                        {
                            mailInfo.Body = message.BodyText;
                        }
                    }

                    mailInfo.BodySize = msg.Size;
                    mailInfo.UserID = account.UserID;
                    mailInfo.MailGuid = msg.UID;
                    mailInfo.FolderID = (int)MailSysFolder.收件箱;
                    mailInfo.FromName = header.MainEntity.From.Mailboxes[0].DisplayName;//.ToAddressListString();
                    mailInfo.FromAddr = header.MainEntity.From.Mailboxes[0].EmailAddress;//.ToAddressListString();

                    if (header.MainEntity.To != null)
                    {
                        StringBuilder toAddr = new StringBuilder();
                        foreach (Address addr in header.MainEntity.To)
                        {
                            if (addr.IsGroupAddress)
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.Append("\"" + (addr as GroupAddress).DisplayName + "\"[");
                                foreach (MailboxAddress mailAddr in (addr as GroupAddress).GroupMembers)
                                {
                                    sb.Append("\"" + mailAddr.DisplayName + "\" <" + mailAddr.EmailAddress + ">,");
                                }
                                toAddr.Append(sb.ToString().TrimEnd(',') + "],");
                            }
                            else
                            {
                                toAddr.Append("\"" + (addr as MailboxAddress).DisplayName + "\" <" + (addr as MailboxAddress).EmailAddress + ">,");
                            }
                        }

                        mailInfo.ToAddr = toAddr.ToString().TrimEnd(',');

                    }

                    if (header.MainEntity.Cc != null)
                    {
                        StringBuilder ccAddr = new StringBuilder();
                        foreach (Address addr in header.MainEntity.Cc)
                        {
                            if (addr.IsGroupAddress)
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.Append("\"" + (addr as GroupAddress).DisplayName + "\"[");
                                foreach (MailboxAddress mailAddr in (addr as GroupAddress).GroupMembers)
                                {
                                    sb.Append("\"" + mailAddr.DisplayName + "\" <" + mailAddr.EmailAddress + ">,");
                                }
                                ccAddr.Append(sb.ToString().TrimEnd(',') + "],");
                            }
                            else
                            {
                                ccAddr.Append("\"" + (addr as MailboxAddress).DisplayName + "\" <" + (addr as MailboxAddress).EmailAddress + ">,");
                            }
                        }

                        mailInfo.CCAddr = ccAddr.ToString().TrimEnd(',');
                    }

                    mailInfo.InputTime = header.MainEntity.Date;
                    if (mailInfo.InputTime.Year < 1000)
                    {
                        mailInfo.InputTime = DateTime.Now;
                    }
                    mailInfo.HasAttachment = header.MainEntity.HasAttachments;
                    mailInfo.Status = (int)MailStatus.UnRead;
                    mailInfo.HasDownload = true;

                    mail.Save(mailInfo);

                    //和附件的存放可以考虑放到一个事务中


                    AttachBO attach = new AttachBO(OTableName.WebMailAttach);
                    foreach (MimeEntity entity in message.Attachments)
                    {
                        string strFileName = entity.ContentDisposition_FileName;
                        if (strFileName == null || strFileName == "")
                        {
                            strFileName = entity.ContentType_Name;
                        }
                        if (strFileName == null || strFileName == "")
                        {
                            strFileName = "无文件名称";
                        }

                        AttachInfo tmp = new AttachInfo();
                        tmp.Name = strFileName;
                        tmp.Type = entity.GetContentType();
                        tmp.Path = attach.Save(entity.Data, strFileName);
                        tmp.Size = entity.Data.Length;
                        tmp.InputTime = DateTime.Now;
                        tmp.CreatorID = account.UserID;
                        tmp.CreatorName = "";
                        tmp.BindID = mailInfo.ID;

                        attach.Save(tmp);
                    }

                    Thread.Sleep(50);
                }
                catch (Exception ex)
                {

                }
            }

            pop3.Disconnect();
            
        }
        
    }
}
